﻿#include "EditorContextMenuView.h"

#include "Widgets/Window.h"
#include "Widgets/RectangleWidget.h"
#include "Widgets/TextWidget.h"
#include "Widgets/ImageWidget.h"
#include "Widgets/Positioners/VerticalPositionerWidget.h"
#include "Widgets/Mouse/MouseWidget.h"

#include "Framework/Editor.h"
#include "Theme/EditorTheme.h"

#include "Window/EditorContextMenuViewModel.h"

void REditorContextMenuView::BindViewModel(TSharedObjectPtr<REditorContextMenuViewModel> InViewModel)
{
    ViewModel=InViewModel;
    ViewModel->OnVisibleMenuChanged.Bind(this,&REditorContextMenuView::OnMenuChanged);
}

void REditorContextMenuView::OnMenuChanged(int64_t InMenuIndex)
{
    //destroy window
    if(Windows.Contains(InMenuIndex))
    {
        Windows[InMenuIndex]->Close();
        Windows.Remove(InMenuIndex);
    }


    //create window
    if(!ViewModel->IsMenuEmpty(InMenuIndex))
    {
        CreateWindow(InMenuIndex);
    }

    for(auto& Pair:Windows)
    {
        Pair.Value->OnLostFocus.BindLambda(
            [this](uint64_t FocusedWindow)
        {
            bool IsFocuseContextMenu=false;
            for(auto& Pair:Windows)
            {
                if(Pair.Value->GetWindowID()==FocusedWindow)
                {
                    IsFocuseContextMenu=true;
                    break;
                }
            }

            if(!IsFocuseContextMenu)
            {
                //整个菜单失去焦点
                ViewModel->OnLostFocus();
            }
        });
    }

       
}

void REditorContextMenuView::CreateWindow(int64_t MenuIndex)
{
    auto Window=NewObject<RWindow>();
    Window->HideSystemBorder();
    RWindowWeakPtr WeakWindow=Window;
    Window->SetWindowSize(ViewModel->GetMenuWidth(MenuIndex)
        ,ViewModel->GetMenuHeight(MenuIndex));
    Window->SetWindowPosition(ViewModel->GetMenuScreenPosition(MenuIndex));
    Window->Show();
    Window->BringToFront();
    Windows.Add(MenuIndex,Window);
    //移除默认的白色背景
    Window->GetRootWidget()->Fill=false;



    auto BackgroundWidget=NewWidget<RRectangleWidget>(Window->GetRootWidget());
    BackgroundWidget->Anchor.Fill(Window->GetRootWidget());
    BackgroundWidget->FillColor= REditor::Get()->CurrentTheme->ForegroundColor;
    BackgroundWidget->BorderSize=REditor::Get()->CurrentTheme->ContextMenuBorderSize;
    BackgroundWidget->BorderColor= REditor::Get()->CurrentTheme->ContextMenuBorderColor;
    BackgroundWidget->Radius= REditor::Get()->CurrentTheme->ContextMenuRadius;
    auto HighlightLine=NewWidget<RRectangleWidget>(Window->GetRootWidget());
    HighlightLine->Visible=[this,MenuIndex](){
        return ViewModel->ShouldHighlight(MenuIndex);
    };
    HighlightLine->Anchor.LeftReference=Window->GetRootWidget();
    HighlightLine->Anchor.LeftOffset=2;
    HighlightLine->Anchor.RightReference=Window->GetRootWidget();
    HighlightLine->Anchor.RightOffset=2;
    HighlightLine->FillColor= REditor::Get()->CurrentTheme->HighlightColor;
    HighlightLine->Radius= 4;
    HighlightLine->Height= ViewModel->NormalLineHeight;
    auto VerticalLayout=NewWidget<RVerticalPositionerWidget>(Window->GetRootWidget());
    RVerticalPositionerWidgetWeakPtr WeakVerticalLayout=VerticalLayout;
    HighlightLine->Anchor.TopReference=[this,MenuIndex,WeakVerticalLayout]() ->RWidgetPtr
    {
        int64_t LineIndex=ViewModel->GetHighlightLineIndex(MenuIndex);
        if(LineIndex==-1)
        {
            return nullptr;
        }
        return WeakVerticalLayout->GetSubWidget(LineIndex);
    };

    VerticalLayout->Anchor.Fill(Window->GetRootWidget());
    VerticalLayout->Spacing=0;

    for(int64_t LineIndex=0;LineIndex< ViewModel->GetMenuLineNum(MenuIndex);++LineIndex)
    {
        auto Line=NewWidget<RWidget>(VerticalLayout);
        Line->Anchor.HorizontalFill(VerticalLayout);
        if(ViewModel->IsSeparator(MenuIndex,LineIndex))
        {
            Line->Height=ViewModel->SepreatorLineHeight;

            auto Separator=NewWidget<RRectangleWidget>(Line);
            Separator->Anchor.HorizontalFill(Line);
            Separator->Y=(ViewModel->SepreatorLineHeight-REditor::Get()->CurrentTheme->SpliterSize)/2;
            Separator->Height=REditor::Get()->CurrentTheme->ContextMenuBorderSize;
            Separator->FillColor= REditor::Get()->CurrentTheme->ContextMenuBorderColor;  

        }
        else
        {
            Line->Height=ViewModel->NormalLineHeight;

            bool bValid=ViewModel->IsValid(MenuIndex,LineIndex);
            if(bValid)
            {
                auto Mouse=NewWidget<RMouseWidget>(Line);
                Mouse->Anchor.Fill(Line);
                Mouse->OnEntered.BindLambda([this,MenuIndex,LineIndex](){
                    ViewModel->OnHovered(MenuIndex,LineIndex);
                });
                Mouse->OnExited.BindLambda([this,MenuIndex,LineIndex](){
                    ViewModel->OnUnHovered(MenuIndex,LineIndex);
                });
                Mouse->OnClicked.BindLambda([this,MenuIndex,LineIndex](const SMouseButtonEvent&){
                    ViewModel->OnClicked(MenuIndex,LineIndex);
                    return true;
                });
            }

            auto Icon=NewWidget<RImageWidget>(Line);
            Icon->X=ViewModel->LineHorizontalPadding;
            Icon->Width=ViewModel->IconSize;
            Icon->Height=ViewModel->IconSize;
            Icon->Anchor.VerticalCenterReference=Line;
            Icon->Image=ViewModel->GetIcon(MenuIndex,LineIndex);

            SColor TextColor=bValid? SColor::White : SColor(0.5,0.5,0.5,1);
            auto Text=NewWidget<RTextWidget>(Line);
            Text->Anchor.VerticalFill(Line);
            Text->X= ViewModel->LineHorizontalPadding 
                + ViewModel->IconSize 
                + ViewModel->LineSpace;
            Text->VerticalAlignment=ETextVerticalAlignment::Center;
            Text->Text=ViewModel->GetText(MenuIndex,LineIndex);
            Text->Color=TextColor;

            auto ShorcutText=NewWidget<RTextWidget>(Line);
            ShorcutText->Anchor.VerticalFill(Line);
            ShorcutText->Anchor.RightReference=Line;
            ShorcutText->Anchor.RightOffset=
                ViewModel->LineHorizontalPadding;
            ShorcutText->X=0;
            ShorcutText->HorizontalAlignment=ETextHorizontalAlignment::Right;
            ShorcutText->VerticalAlignment=ETextVerticalAlignment::Center;
            ShorcutText->Text=ViewModel->GetShorcutText(MenuIndex,LineIndex);
            ShorcutText->Color=TextColor;

            if(ViewModel->IsExpandIconVisible(MenuIndex,LineIndex))
            {
                auto ExpandIcon=NewWidget<RImageWidget>(Line);
                ExpandIcon->Anchor.RightReference=Line;
                ExpandIcon->Anchor.RightOffset=ViewModel->LineHorizontalPadding;
                ExpandIcon->Width=ViewModel->ExpandIconSize;
                ExpandIcon->Height=ViewModel->ExpandIconSize;
                ExpandIcon->Anchor.VerticalCenterReference=Line;
                ExpandIcon->Image=ViewModel->GetExpandIcon();
            }

        }
    }

}
